﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using XStudio.XCRF.Data.Entities;
using XStudio.XCRF.Utilities.MD5Encryption;
using XStudio.XCRF.Data.Entities.BasicInfo;
using XStudio.XCRF.Data.Enums;
using XStudio.XCRF.Data.Entities.LabCheck;
using XStudio.XCRF.Data.Entities.CureInfo;
using XStudio.XCRF.Data.Entities.TongueAndPulse;

namespace XStudio.XCRF.Data
{
    /// <summary>
    /// 数据库初始化器
    /// </summary>
    public class XCRFInitializer : DropCreateDatabaseIfModelChanges<XCRFContext>
    {

        #region 核心

        /// <summary>
        /// 构造新的数据库初始化器
        /// </summary>
        public XCRFInitializer()
        {

        }

        protected override void Seed(XCRFContext context)
        {
            ConfigDatabase(context);
            AddInitialData(context);
            AddDiseaseAndHerbs(context);
            AddTongueData(context);
            AddPulseData(context);
        }
        #endregion 核心

        #region 初始化阶段函数

        /// <summary>
        /// 配置数据库额外设置
        /// </summary>
        /// <param name="context"></param>
        private void ConfigDatabase(XCRFContext context)
        {
            #region 添加索引
            Database db = context.Database;
            db.ExecuteSqlCommand("create index IX_Members_LoginName on Members(LoginName)");
            db.ExecuteSqlCommand("create index IX_Hospitals_Code on Hospitals(Code)");
            db.ExecuteSqlCommand("create index IX_CRFs_HospitalID on CRFs(HospitalID)");
            db.ExecuteSqlCommand("create index IX_BasicInfoes_CRFID on BasicInfoes(CRFID)");
            db.ExecuteSqlCommand("create index IX_LabChecks_CRFID on LabChecks(CRFID)");
            db.ExecuteSqlCommand("create index IX_CureInfoes_CRFID on CureInfoes(CRFID)");
            db.ExecuteSqlCommand("alter table Diseases add constraint UQ_Diseases_Name unique (Name)");
            db.ExecuteSqlCommand("alter table Herbs add constraint UQ_Herbs_Name unique (Name)");
            db.ExecuteSqlCommand("alter table TongueColors add constraint UQ_TongueColors_Name unique (Name)");
            db.ExecuteSqlCommand("alter table TongueShapes add constraint UQ_TongueShapes_Name unique (Name)");
            db.ExecuteSqlCommand("alter table TongueStatus add constraint UQ_TongueStatuses_Name unique (Name)");
            db.ExecuteSqlCommand("alter table PulseFloats add constraint UQ_PulseFloats_Name unique (Name)");
            db.ExecuteSqlCommand("alter table PulseDeeps add constraint UQ_PulseDeeps_Name unique (Name)");
            db.ExecuteSqlCommand("alter table PulseSlows add constraint UQ_PulseSlows_Name unique (Name)");
            db.ExecuteSqlCommand("alter table PulseRapids add constraint UQ_PulseRapids_Name unique (Name)");
            db.ExecuteSqlCommand("alter table PulseFeebles add constraint UQ_PulseFeebles_Name unique (Name)");
            db.ExecuteSqlCommand("alter table PulseExcesses add constraint UQ_PulseExcesses_Name unique (Name)");
            #endregion 添加索引
        }

        /// <summary>
        /// 添加初始数据
        /// </summary>
        /// <param name="context"></param>
        private void AddInitialData(XCRFContext context)
        {
            #region 添加管理员
            DateTime time = DateTime.Now;
            Hospital hospital = new Hospital
            {
                Name = "普陀医院",
                Code = "00",
                Address = "上海市普陀区",
                Phone = "021-12345678",
                Email = "putuo@abc.com",
                Website = "http://www.abc.com",
                Detail = "医疗设施齐全，服务态度极好！",
                CreateTime = time,
                LastModifyTime = time
            };
            Member admin = new Member
            {
                LoginName = "admin",
                RealName = "管理员",
                Password = "admin",
                Gender = (byte)GenderTypes.Male,
                Type = (byte)MemberTypes.Administrator,
                Email = "123@abc.com",
                Phone = "123456",
                Profile = "系统默认账号",
                Hospital = hospital,
                CreateTime = time,
                LastModifyTime = time
            };
            context.Members.Add(admin);
            context.SaveChanges();
            #endregion 添加管理员

            //下面为批量测试数据
            #region 批量测试
            context.DebugModeOn = false;
            context.CurrentMember = admin;
            Patient patient = new Patient
            {
                IDCard = "210106198907233312",
                Name = "张三",
                Gender = (byte)GenderTypes.Male,
                TreatDepart = "药科",
                Nationality = "汉族",
                Birthday = new DateTime(1989, 7, 23),
                Job = "水电工",
                JobKind="水电",
                Address = "上海市普陀区",
                Phone = "021-12121212",
            };
            CRF crf = new CRF
            {
                Patient = patient,
                HospitalCode = "00",
                CrfCode = "0001",
                HospitalID = hospital.ID,
                ResearcherID = context.CurrentMember.ID,
            };
            context.CRFs.Add(crf);
            BasicInfo basicInfo = new BasicInfo
            {
                CRF = crf
            };
            context.BasicInfoes.Add(basicInfo);
            LabCheck labCheck = new LabCheck
            {
                CRF = crf,
                Time = time,
                PRO = 0,
                GLU = 0,
                LEU = 0,
                BLD = 0,
                BXB = 0,
                FB = 0
            };
            context.LabChecks.Add(labCheck);
            context.SaveChanges();

            for (int i = 1; i < 2; i++)
            {
               
                Hospital h = new Hospital
                {
                    
                    Name = "华山医院",
                    Code = "0" + i,
                    Address = "上海市普陀区",
                    Phone = i.ToString(),
                    Email = i + "@abc.com",
                    Website = "http://www.abc.com",
                    Detail = "这是副医院",
                    
                 };
                Member m = new Member
                {
                    LoginName = "owner" + i,
                    RealName = "主管" + i,
                    Password = "admin",
                    Type = (byte)MemberTypes.Owner,
                    Email = "123@abc.com",
                    Phone = "123456",
                    Profile = "",
                    Hospital = h,
                };
                context.Members.Add(m);
                for (int j = 0; j < 3; j++)
                {
                    Member mr = new Member
                    {
                        LoginName = "Researcher" + i + "_" + j,
                        RealName = "用户" + i + "_" + j,
                        Password = "admin",
                        Type = (byte)MemberTypes.Researcher,
                        Email = "123@abc.com",
                        Phone = "123456",
                        Profile = "",
                        Hospital = h
                    };
                    context.Members.Add(mr);
                }
            }
            context.SaveChanges();
            #endregion 批量测试
        }

        /// <summary>
        /// 添加单症和用药
        /// </summary>
        /// <param name="context"></param>
        private void AddDiseaseAndHerbs(XCRFContext context)
        {
            Dictionary<string, string[]> relations = new Dictionary<string, string[]>();
            relations.Add("脾气虚", new string[] { "黄芪", "党参", "茯苓", "白术" });
            relations.Add("肺气虚", new string[] { "黄芪", "白术", "防风" });
            relations.Add("脾阳虚", new string[] { "党参", "白术", "炙甘草", "干姜" });
            relations.Add("气滞", new string[] { "香附", "苍术", "川芎", "神曲", "栀子" });
            relations.Add("血虚", new string[] { "熟地", "当归", "白芍", "川芎" });
            relations.Add("血热", new string[] { "犀角", "生地黄", "丹皮", "赤芍" });
            relations.Add("血瘀", new string[] { "灵脂", "当归", "川芎", "桃仁", "丹皮", "赤芍", "乌药", "玄胡索", "甘草", "香附", "红花", "枳壳" });
            relations.Add("肝阴虚", new string[] { "沙参", "生地", "麦冬", "枸杞子", "川楝子", "当归" });
            relations.Add("肾阴虚", new string[] { "熟地", "山药", "枸杞", "山茱萸", "川牛膝", "菟丝子", "鹿胶", "龟胶" });
            relations.Add("肾阳虚", new string[] { "熟地", "山药", "山茱萸", "枸杞子", "菟丝子", "鹿角胶", "杜仲", "肉桂", "当归", "附子" });
            relations.Add("湿热", new string[] { "槐角", "地榆", "侧柏叶", "黄芩", "黄连", "黄柏", "荆芥", "防风", "枳壳", "当归" });
            relations.Add("寒湿", new string[] { "厚朴", "白术", "木瓜", "木香", "草果仁", "大腹子", "附子", "白茯苓", "干姜", "炙甘草" });
            relations.Add("湿浊", new string[] { "苍术", "陈皮", "厚朴", "甘草" });
            relations.Add("其他", new string[] { });

            IEnumerable<string> herbNames = relations.SelectMany(relation => relation.Value).Distinct();
            Dictionary<string, Herb> herbs = new Dictionary<string, Herb>();
            foreach (string herbName in herbNames)
            {
                Herb herb = new Herb { Name = herbName };
                herbs.Add(herbName, herb);
                context.Herbs.Add(herb);
            }

            foreach (KeyValuePair<string, string[]> relation in relations)
            {
                Disease disease = new Disease
                {
                    Name = relation.Key,
                    Herbs = relation.Value.Select(herbName => herbs[herbName]).ToList()
                };
                context.Diseases.Add(disease);
            }
            context.SaveChanges();
        }

        /// <summary>
        /// 添加舌象数据
        /// </summary>
        /// <param name="context"></param>
        private void AddTongueData(XCRFContext context)
        {
            string[] shapeNames = { "苍老舌", "娇嫩舌", "裂纹", "芒刺", "胖大舌", "瘦薄" };
            string[] colorNames = { "淡白舌", "淡红舌", "红舌", "绛舌", "青舌", "紫舌" };
            string[] statusNames = { "紫舌", "短缩", "麻痹", "强硬", "舌纵", "吐弄", "歪斜", "痿软" };
            string[] furCharacterNames = { "厚", "薄", "润", "燥", "腐", "腻", "剥落有根苔", "剥落无根苔" };
            string[] furColorNames = { "白苔", "黑苔", "黄苔", "灰苔" };
            foreach (string name in shapeNames)
                context.TongueShapes.Add(new TongueShape { Name = name });
            foreach (string name in colorNames)
                context.TongueColors.Add(new TongueColor { Name = name });
            foreach (string name in statusNames)
                context.TongueStatus.Add(new TongueStatus { Name = name });
            foreach (string name in furCharacterNames)
                context.TongueFurCharacters.Add(new TongueFurCharacter { Name = name });
            foreach (string name in furColorNames)
                context.TongueFurColors.Add(new TongueFurColor { Name = name });
            context.SaveChanges();
        }

        /// <summary>
        /// 添加脉象数据
        /// </summary>
        /// <param name="context"></param>
        private void AddPulseData(XCRFContext context)
        {
            string[] floatNames = { "浮脉", "洪脉", "濡脉", "散脉", "芤脉", "革脉" };
            string[] deepNames = { "沉脉", "伏脉", "弱脉", "牢脉" };
            string[] slowNames = {"迟脉", "缓脉", "涩脉", "结脉" };
            string[] rapidNames = { "数脉", "疾脉", "促脉", "动脉" };
            string[] feebleNames = { "虚脉", "细脉", "微脉", "代脉", "短脉" };
            string[] excessNames = { "实脉", "滑脉", "弦脉", "紧脉", "长脉" };
            foreach (string name in floatNames)
                context.PulseFloats.Add(new PulseFloat { Name = name });
            foreach (string name in deepNames)
                context.PulseDeeps.Add(new PulseDeep { Name = name });
            foreach (string name in slowNames)
                context.PulseSlows.Add(new PulseSlow { Name = name });
            foreach (string name in rapidNames)
                context.PulseRapids.Add(new PulseRapid { Name = name });
            foreach (string name in feebleNames)
                context.PulseFeebles.Add(new PulseFeeble { Name = name });
            foreach (string name in excessNames)
                context.PulseExcesses.Add(new PulseExcess { Name = name });
            context.SaveChanges();
        }
        #endregion 初始化阶段函数
    }
}
